package inge_soft.gestoriusNuevo.business.service.implementation;

import inge_soft.gestoriusNuevo.business.service.abstraction.IInstitucionService;
import inge_soft.gestoriusNuevo.persistence.DAO.Exceptions.Abstraction.GestoriusException;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.IDomicilioDAO;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.IDomicilioTipificadoDAO;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.IEstadoInstitucionDAO;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.IInstitucionDAO;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.ILocalidadDAO;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.IPaisDAO;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.ITipoDomicilioDAO;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.IUsuarioRegistradoDAO;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.DomicilioTipificado;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.EstadoInstitucion;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Institucion;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Localidad;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Pais;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Provincia;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.TipoDomicilio;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.UsuarioRegistrado;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("institucionService")
public class InstitucionService implements IInstitucionService {

	@Autowired
	@Qualifier("usuarioRegistradoDAO")
	IUsuarioRegistradoDAO usuarioRegistradoDAO;

	@Autowired
	@Qualifier("domicilioTipificadoDAO")
	IDomicilioTipificadoDAO domicilioTipificadoDAO;
	
	@Autowired
	@Qualifier("tipoDomicilioDAO")
	ITipoDomicilioDAO tipoDomicilioDAO;

	@Autowired
	@Qualifier("paisDAO")
	IPaisDAO paisDAO;

	@Autowired
	@Qualifier("localidadDAO")
	ILocalidadDAO localidadDAO;

	@Autowired
	@Qualifier("institucionDAO")
	IInstitucionDAO institucionDAO;

	@Autowired
	@Qualifier("estadoInstitucionDAO")
	IEstadoInstitucionDAO estadoInstitucionDAO;

	@Transactional
	public List<Institucion> obtenerInstituciones(String nickUsuario)
			throws DataAccessException {
		return usuarioRegistradoDAO.obtenerInstituciones(nickUsuario);
	}

	@Transactional
	public void crearInstitucion(String nickUsuario,
			Institucion institucionNueva) throws DataAccessException {

		// Obtiene el usuario logueado
		UsuarioRegistrado userR = usuarioRegistradoDAO.findByNick(nickUsuario);

		// Crea la institucion dentro del usuario
		institucionDAO.crearInstitucion(userR.getUsuario(), institucionNueva,
				estadoInstitucionDAO.buscarEstado("Activa"));

		// Actualiza los datos del usuario
		usuarioRegistradoDAO.modificarUsuario(userR);
	}

	@Transactional
	public void modificarInstitucion(String nickUsuario,
			Institucion institucionModificada) throws DataAccessException {
		// usuarioRegistradoDAO.modificarInstitucion(nickUsuario,
		// institucionModificada);

		// Obtiene el usuario logueado
		UsuarioRegistrado userR = usuarioRegistradoDAO.findByNick(nickUsuario);

		// Modifica la institucion dentro del usuario
		institucionDAO.modificarInstitucion(userR.getUsuario(),
				institucionModificada);

		// Actualiza los datos del usuario
		usuarioRegistradoDAO.modificarUsuario(userR);

	}

	@Transactional
	// TODO
	public void crearDomicilio(String nickUsuario,
			Institucion institucionModificada, DomicilioTipificado domicilio)
			throws DataAccessException {
		// Persisto el nuevo domicilio
		domicilio.setTipoDomicilio(tipoDomicilioDAO.buscarEstado(domicilio.getTipoDomicilio().getTipo()));
		domicilioTipificadoDAO.crear(domicilio,institucionModificada);

		// Agrego el domicilio nuevo a la lista de domicilios de la institucion
		institucionModificada.getDomicilios().add(domicilio);

		// Busco el usuario y persisto los cambios en la institucion
		//UsuarioRegistrado userR = usuarioRegistradoDAO.findByNick(nickUsuario);
		//institucionDAO.modificarInstitucion(userR.getUsuario(),
		//		institucionModificada);
	}

	@Transactional
	// TODO
	public void modificarDomicilio(String nickUsuario,
			Institucion institucionModificada, DomicilioTipificado domicilio)
			throws DataAccessException {
		// Obtiene el usuario logueado
		UsuarioRegistrado userR = usuarioRegistradoDAO.findByNick(nickUsuario);
		
		//Persiste los cambios en el domicilio
		domicilioTipificadoDAO.modificar(domicilio, institucionModificada);

		//Persiste los cambios en la institucion
		//institucionDAO.modificarInstitucion(userR.getUsuario(), institucionModificada);

		//Persiste los cambios en el usuario 
		//usuarioRegistradoDAO.modificarUsuario(userR);
	}

	@Transactional
	public List<EstadoInstitucion> obtenerEstadosInstitucion() {
		return usuarioRegistradoDAO.obtenerEstadosInstitucion();
	}

	public List<TipoDomicilio> obtenerTipoDomicilios()
			throws GestoriusException {
		return domicilioTipificadoDAO.obtenerTipoDomicilios();
	}

	public List<Provincia> obtenerProvincias(Pais pais)
			throws GestoriusException {
		return paisDAO.obtenerProvincias(pais);
	}

	public List<Localidad> obtenerLocalidades(Provincia provincia)
			throws GestoriusException {
		return localidadDAO.obtenerLocalidades(provincia);
	}

	public List<Pais> obtenerPaises() throws GestoriusException {
		return paisDAO.obtenerTodosLosPaisesOrdenadosPorNombreAscendente();
	}

}